using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace MatrixFramework.Core.Configuration;

/// <summary>
/// 环境服务接口
/// </summary>
public interface IEnvironmentService
{
    /// <summary>
    /// 获取当前环境名称
    /// </summary>
    string EnvironmentName { get; }

    /// <summary>
    /// 是否为开发环境
    /// </summary>
    bool IsDevelopment { get; }

    /// <summary>
    /// 是否为测试环境
    /// </summary>
    bool IsStaging { get; }

    /// <summary>
    /// 是否为生产环境
    /// </summary>
    bool IsProduction { get; }

    /// <summary>
    /// 获取环境变量
    /// </summary>
    /// <param name="key">变量名</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>环境变量值</returns>
    string GetEnvironmentVariable(string key, string? defaultValue = null);

    /// <summary>
    /// 获取强类型环境变量
    /// </summary>
    /// <typeparam name="T">变量类型</typeparam>
    /// <param name="key">变量名</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>环境变量值</returns>
    T GetEnvironmentVariable<T>(string key, T defaultValue = default!);

    /// <summary>
    /// 获取所有环境变量
    /// </summary>
    /// <param name="prefix">前缀过滤（可选）</param>
    /// <returns>环境变量字典</returns>
    Dictionary<string, string> GetAllEnvironmentVariables(string? prefix = null);

    /// <summary>
    /// 设置环境变量
    /// </summary>
    /// <param name="key">变量名</param>
    /// <param name="value">变量值</param>
    /// <param name="isPermanent">是否永久设置</param>
    void SetEnvironmentVariable(string key, string? value, bool isPermanent = false);

    /// <summary>
    /// 删除环境变量
    /// </summary>
    /// <param name="key">变量名</param>
    void RemoveEnvironmentVariable(string key);

    /// <summary>
    /// 获取连接字符串
    /// </summary>
    /// <param name="name">连接字符串名称</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>连接字符串</returns>
    string GetConnectionString(string name, string? defaultValue = null);

    /// <summary>
    /// 获取所有连接字符串
    /// </summary>
    /// <returns>连接字符串字典</returns>
    Dictionary<string, string> GetAllConnectionStrings();

    /// <summary>
    /// 设置连接字符串
    /// </summary>
    /// <param name="name">连接字符串名称</param>
    /// <param name="connectionString">连接字符串</param>
    void SetConnectionString(string name, string? connectionString);

    /// <summary>
    /// 删除连接字符串
    /// </summary>
    /// <param name="name">连接字符串名称</param>
    void RemoveConnectionString(string name);

    /// <summary>
    /// 获取应用设置
    /// </summary>
    /// <param name="key">设置键</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>设置值</returns>
    string GetAppSetting(string key, string? defaultValue = null);

    /// <summary>
    /// 获取强类型应用设置
    /// </summary>
    /// <typeparam name="T">设置类型</typeparam>
    /// <param name="key">设置键</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>设置值</returns>
    T GetAppSetting<T>(string key, T defaultValue = default!);

    /// <summary>
    /// 设置应用设置
    /// </summary>
    /// <param name="key">设置键</param>
    /// <param name="value">设置值</param>
    void SetAppSetting(string key, string? value);

    /// <summary>
    /// 获取应用配置节
    /// </summary>
    /// <typeparam name="T">配置类型</typeparam>
    /// <param name="sectionName">配置节名称</param>
    /// <returns>配置对象</returns>
    T GetSection<T>(string sectionName) where T : class, new();

    /// <summary>
    /// 重新加载配置
    /// </summary>
    void ReloadConfiguration();

    /// <summary>
    /// 验证配置完整性
    /// </summary>
    /// <param name="requiredKeys">必需的配置键</param>
    /// <param name="requiredConnectionStrings">必需的连接字符串</param>
    /// <returns>验证结果</returns>
    Task<ConfigurationValidationResult> ValidateConfigurationAsync(IEnumerable<string>? requiredKeys = null, IEnumerable<string>? requiredConnectionStrings = null);

    /// <summary>
    /// 获取环境配置信息
    /// </summary>
    /// <returns>环境信息</returns>
    EnvironmentInfo GetEnvironmentInfo();

    /// <summary>
    /// 检查健康状态
    /// </summary>
    /// <returns>健康状态</returns>
    Task<EnvironmentHealthStatus> CheckHealthAsync();
}

/// <summary>
/// 配置验证结果
/// </summary>
public class ConfigurationValidationResult
{
    public bool IsValid { get; set; }
    public IReadOnlyList<string> Errors { get; private set; } = new List<string>();
    public IReadOnlyList<string> Warnings { get; private set; } = new List<string>();
    public IReadOnlyDictionary<string, string> ValidatedSettings { get; private set; } = new Dictionary<string, string>();
    public DateTime ValidationTime { get; set; } = DateTime.UtcNow;

    /// <summary>
    /// 添加错误信息
    /// </summary>
    /// <param name="error">错误信息</param>
    public void AddError(string error)
    {
        if (string.IsNullOrEmpty(error)) return;

        var errors = new List<string>(Errors);
        errors.Add(error);
        Errors = errors.AsReadOnly();
    }

    /// <summary>
    /// 添加警告信息
    /// </summary>
    /// <param name="warning">警告信息</param>
    public void AddWarning(string warning)
    {
        if (string.IsNullOrEmpty(warning)) return;

        var warnings = new List<string>(Warnings);
        warnings.Add(warning);
        Warnings = warnings.AsReadOnly();
    }

    /// <summary>
    /// 添加验证设置
    /// </summary>
    /// <param name="key">设置键</param>
    /// <param name="value">设置值</param>
    public void AddValidatedSetting(string key, string value)
    {
        if (string.IsNullOrEmpty(key)) return;

        var validatedSettings = new Dictionary<string, string>(ValidatedSettings);
        validatedSettings[key] = value ?? string.Empty;
        ValidatedSettings = validatedSettings.AsReadOnly();
    }
}

/// <summary>
/// 环境信息
/// </summary>
public class EnvironmentInfo
{
    public string Name { get; set; } = string.Empty;
    public string Version { get; set; } = string.Empty;
    public string BuildDate { get; set; } = string.Empty;
    public string MachineName { get; set; } = string.Empty;
    public string Platform { get; set; } = string.Empty;
    public string FrameworkVersion { get; set; } = string.Empty;
    public string ApplicationPath { get; set; } = string.Empty;
    public string WorkingDirectory { get; set; } = string.Empty;
    public DateTime StartTime { get; set; }
    public IReadOnlyDictionary<string, string> CustomProperties { get; private set; } = new Dictionary<string, string>();

    /// <summary>
    /// 添加自定义属性
    /// </summary>
    /// <param name="key">属性键</param>
    /// <param name="value">属性值</param>
    public void AddCustomProperty(string key, string value)
    {
        if (string.IsNullOrEmpty(key)) return;

        var customProperties = new Dictionary<string, string>(CustomProperties);
        customProperties[key] = value ?? string.Empty;
        CustomProperties = customProperties.AsReadOnly();
    }

    /// <summary>
    /// 添加多个自定义属性
    /// </summary>
    /// <param name="properties">属性字典</param>
    public void AddCustomProperties(IDictionary<string, string> properties)
    {
        if (properties == null) return;

        var customProperties = new Dictionary<string, string>(CustomProperties);
        foreach (var kvp in properties.Where(p => !string.IsNullOrEmpty(p.Key)))
        {
            customProperties[kvp.Key] = kvp.Value ?? string.Empty;
        }
        CustomProperties = customProperties.AsReadOnly();
    }
}

/// <summary>
/// 环境健康状态
/// </summary>
public class EnvironmentHealthStatus
{
    public bool IsHealthy { get; set; }
    public string Status { get; set; } = string.Empty;
    public IReadOnlyList<HealthCheck> HealthChecks { get; private set; } = new List<HealthCheck>();
    public DateTime CheckTime { get; set; } = DateTime.UtcNow;
    public TimeSpan Uptime { get; set; }

    /// <summary>
    /// 添加健康检查项
    /// </summary>
    /// <param name="healthCheck">健康检查项</param>
    public void AddHealthCheck(HealthCheck healthCheck)
    {
        if (healthCheck == null) return;

        var healthChecks = new List<HealthCheck>(HealthChecks);
        healthChecks.Add(healthCheck);
        HealthChecks = healthChecks.AsReadOnly();
    }

    /// <summary>
    /// 添加多个健康检查项
    /// </summary>
    /// <param name="healthChecks">健康检查项列表</param>
    public void AddHealthChecks(IEnumerable<HealthCheck> healthChecks)
    {
        if (healthChecks == null) return;

        var healthCheckList = new List<HealthCheck>(HealthChecks);
        healthCheckList.AddRange(healthChecks.Where(hc => hc != null));
        HealthChecks = healthCheckList.AsReadOnly();
    }
}

/// <summary>
/// 健康检查项
/// </summary>
public class HealthCheck
{
    public string Name { get; set; } = string.Empty;
    public bool IsHealthy { get; set; }
    public string Message { get; set; } = string.Empty;
    public TimeSpan Duration { get; set; }
    public IReadOnlyDictionary<string, object> Data { get; private set; } = new Dictionary<string, object>();

    /// <summary>
    /// 添加数据项
    /// </summary>
    /// <param name="key">数据键</param>
    /// <param name="value">数据值</param>
    public void AddData(string key, object value)
    {
        if (string.IsNullOrEmpty(key)) return;

        var data = new Dictionary<string, object>(Data);
        data[key] = value ?? string.Empty;
        Data = data.AsReadOnly();
    }

    /// <summary>
    /// 添加多个数据项
    /// </summary>
    /// <param name="dataItems">数据字典</param>
    public void AddData(IDictionary<string, object> dataItems)
    {
        if (dataItems == null) return;

        var data = new Dictionary<string, object>(Data);
        foreach (var kvp in dataItems.Where(d => !string.IsNullOrEmpty(d.Key)))
        {
            data[kvp.Key] = kvp.Value ?? string.Empty;
        }
        Data = data.AsReadOnly();
    }
}